﻿using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace Launcher;

public partial class Downloader
{
    public enum DownloadState
    {
        Free,
        RequestInfo,
        Downloading,
        Freezing,
    }
    
    private const int RetryTime = 10;
    private const string DownloadedList = "downloaded.list";
    private const string ResourceInfo = "resources.json";
    private static string DownloadTmpPath => Path.Combine(Setting.Instance.CachePath, "tmp");
    private static readonly Dictionary<string, Downloader> Downloaders = new();

    public static Downloader GetDownloader(Channel channel)
    {
        if (!Downloaders.TryGetValue(channel.UniqueIdentification, out var downloader))
        {
            downloader = new Downloader(channel.UniqueIdentification);
            Downloaders.Add(channel.UniqueIdentification, downloader);
        }
        return downloader;
    }
    
    public static bool HasLocalCache(Channel channel)
    {
        return Directory.Exists(Path.Combine(Setting.Instance.CachePath,UniqueIdentificationToFolderName(channel.UniqueIdentification)));
    }

    public static string GetLocalCacheVersion(Channel channel)
    {
        if (!HasLocalCache(channel))
        {
            return "--";
        }

        try
        {
            var resourceInfoPath = Path.Combine(Setting.Instance.CachePath, UniqueIdentificationToFolderName(channel.UniqueIdentification), ResourceInfo);
            var resourcesInfo = JsonSerializer.Deserialize<ResourceInfo>(File.ReadAllText(resourceInfoPath));
            return resourcesInfo?.Version ?? "--";
        }
        catch (Exception e)
        {
            Console.Error.WriteLine(e);
            return "--";
        }
    }
    
    public static string GetLocalCacheSize(Channel channel)
    {
        if (!HasLocalCache(channel))
        {
            return "--";
        }

        try
        {
            var resourceInfoPath = Path.Combine(Setting.Instance.CachePath, UniqueIdentificationToFolderName(channel.UniqueIdentification), ResourceInfo);
            var resourcesInfo = JsonSerializer.Deserialize<ResourceInfo>(File.ReadAllText(resourceInfoPath));
            if (resourcesInfo == null)
            {
                return "--";
            }

            var totalSize = resourcesInfo.Resources.Sum(x => x.Size);
            return Utils.ByteSizeFormat(totalSize);
        }
        catch (Exception e)
        {
            Console.Error.WriteLine(e);
            return "--";
        }
    }
    
    private static readonly Regex InvalidFileNameCharsRegex = new Regex("[" + Regex.Escape(new string(Path.GetInvalidFileNameChars())) + "]");
    private static readonly Regex InvalidPathCharsRegex = new Regex("[" + Regex.Escape(new string(Path.GetInvalidPathChars())) + "]");
    public static string UniqueIdentificationToFolderName(string uniqueIdentification)
    {
        string validPath = InvalidPathCharsRegex.Replace(uniqueIdentification, "_");
        validPath = InvalidFileNameCharsRegex.Replace(validPath, "_");
        validPath = validPath.Trim();
        return validPath;
    }
}